// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cassert>
#include "CasTouch.h"
#include "CasLog.h"

CasTouch::CasTouch(CasSocket *casSocket)
{
    Init(casSocket);
}

CasTouch::~CasTouch()
{
    delete m_streamBuildSender;
}

void CasTouch::Init(CasSocket *casSocket)
{
    m_streamBuildSender = new CasStreamBuildSender(casSocket);
}

bool CasTouch::SendTouchEvent(int id, int action, int x, int y, int pressure, int time, int orientation, int height, int width)
{
    CasTouchEventMsg touchEventMsg;
    touchEventMsg.id = static_cast<uint8_t>(id);
    touchEventMsg.action = static_cast<uint8_t>(action);
    touchEventMsg.x = (unsigned short)htons(x);
    touchEventMsg.y = (unsigned short)htons(y);
    touchEventMsg.pressure = (unsigned short)htons(pressure);
    touchEventMsg.time = htonl(time);
    touchEventMsg.orientation = static_cast<uint8_t>(orientation);
    touchEventMsg.height = (unsigned short)htons(height);
    touchEventMsg.width = (unsigned short)htons(width);
    DBG("time : %d", time);
    
    if (m_streamBuildSender == nullptr) {
        return false;
    }
    int ret = m_streamBuildSender->SendDataToServer(CasMsgType::TouchInput, &touchEventMsg, sizeof(CasTouchEventMsg));
    if (ret != static_cast<int>(sizeof(CasTouchEventMsg))) {
        ERR("Failed to send touch event, aimed to send:%d, sent:%d", (int)sizeof(CasTouchEventMsg), ret);
        return false;
    }
    return true;
}

bool CasTouch::SendKeyEvent(uint16_t keycode, uint16_t action)
{
    CasKeyEventMsg keyEventMsg { 0, 0 };
    keyEventMsg.keycode = (unsigned short) htons(keycode);
    keyEventMsg.action = (unsigned short) htons(action);

    if (m_streamBuildSender == nullptr) {
        return false;
    }

    int ret = m_streamBuildSender->SendDataToServer(CasMsgType::KeyEventInput, &keyEventMsg, sizeof(CasKeyEventMsg));
    if (ret != static_cast<int>(sizeof(CasKeyEventMsg))) {
        ERR("Failed to send key event, aimed to send:%d, sent:%d", (int)sizeof(CasKeyEventMsg), ret);
        return false;
    }
    return true;
}

bool CasTouch::SendMotionEvent(uint16_t masterAxis, int32_t masterValue, uint16_t secondaryAxis, int32_t secondaryValue)
{
    CasMotionEventMsg motionEventMsg { 0, 0, 0, 0 };
    motionEventMsg.masterAxis = masterAxis;
    motionEventMsg.secondaryAxis = secondaryAxis;
    motionEventMsg.masterValue = masterValue;
    motionEventMsg.secondaryValue = secondaryValue;

    if (nullptr == m_streamBuildSender) {
        return false;
    }

    int ret =
        m_streamBuildSender->SendDataToServer(CasMsgType::MotionEventInput, &motionEventMsg, sizeof(CasMotionEventMsg));
    if (ret != static_cast<int>(sizeof(CasMotionEventMsg))) {
        ERR("Error: failed to send motion event, aimed to Send:%d, sent:%d", (int)sizeof(CasMotionEventMsg), ret);
        return false;
    }
    return true;
}